/** @file

  Copyright (C) 2022 - 2023, Phytium Technology Co., Ltd. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <Library/ArmPlatformLib.h>
#include <Library/DebugLib.h>
#include <Library/HobLib.h>
#include <Library/PcdLib.h>
#include <Library/IoLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/ArmSmcLib.h>
#include <Ec.h>

UINT32  mEcDataPort;
UINT32  mEcCommandPort;

//Wait till EC I/P buffer is free
STATIC
UINT8
EcIbFree (
  )
{
  UINT8 Status;
  do {
  	Status = MmioRead8 (mEcCommandPort);
  } while (Status & 2);
  return SUCCESS;
}

//Wait till EC O/P buffer is full
STATIC
UINT8
EcObFull (
  )
{
  UINT8 Status;
  do {
  	Status = MmioRead8 (mEcCommandPort);
  } while(!(Status & 1));
  return SUCCESS;
}

//Send EC command
UINT8
EcWriteCmd (
  UINT8 Cmd
  )
{
  EcIbFree ();
  MmioWrite8 (mEcCommandPort, Cmd);
  return SUCCESS;
}

//Write Data from EC data port
UINT8
EcWriteData (
  UINT8 Data
  )
{
  EcIbFree ();
  MmioWrite8 (mEcDataPort, Data);
  return SUCCESS;
}

//Read Data from EC data Port
UINT8
EcReadData (
  UINT8 *PData
  )
{
  //暂时修改
  *PData = MmioRead8 (mEcDataPort);
  EcObFull ();
  *PData = MmioRead8 (mEcDataPort);
  return SUCCESS;
}

//Read Data from EC Memory from location pointed by Index
UINT8
EcReadMem (
  UINT8 Index,
  UINT8 *Data
  )
{
  UINT8 Cmd;
  Cmd = SMC_READ_EC;
  EcWriteCmd (Cmd);
  EcWriteData (Index);
  EcReadData (Data);
  return SUCCESS;
}

//Write Data to EC memory at location pointed by Index
UINT8
EcWriteMem (
  UINT8 Index,
  UINT8 Data
  )
{
  UINT8 Cmd;
  Cmd = SMC_WRITE_EC;
  EcWriteCmd (Cmd);
  EcWriteData (Index);
  EcWriteData (Data);
  return SUCCESS;
}

EFI_STATUS
EcInit (
  VOID
  )
{
  UINT32  LpcBaseAddr;
  LpcBaseAddr = FixedPcdGet64 (PcdEcBaseAddress);
  DEBUG ((EFI_D_INFO, "LpcBaseAddr : 0x%08x\n", LpcBaseAddr));
  mEcDataPort = LpcBaseAddr + EC_DATA;
  mEcCommandPort = LpcBaseAddr + EC_SC;

  return EFI_SUCCESS;
}
